home *** CD-ROM | disk | FTP | other *** search
/ Network CD 2 / Network CD - Volume 2.iso / programs / internet / mail / smailsr2.lha / SMail / src / RCS / resolve.c,v < prev    next >
Encoding:
Text File  |  1993-11-30  |  11.7 KB  |  489 lines

  1. head    2.1;
  2. access;
  3. symbols
  4.     C_2:2.1
  5.     C_1:1.2;
  6. locks; strict;
  7. comment    @ * @;
  8.  
  9.  
  10. 2.1
  11. date    93.11.23.19.58.39;    author Aussem;    state Exp;
  12. branches;
  13. next    1.4;
  14.  
  15. 1.4
  16. date    93.11.20.21.03.02;    author Aussem;    state Exp;
  17. branches;
  18. next    1.3;
  19.  
  20. 1.3
  21. date    93.11.20.20.19.25;    author Aussem;    state Exp;
  22. branches;
  23. next    1.2;
  24.  
  25. 1.2
  26. date    93.10.26.23.05.24;    author Aussem;    state Exp;
  27. branches;
  28. next    1.1;
  29.  
  30. 1.1
  31. date    93.10.24.00.20.08;    author Aussem;    state Exp;
  32. branches;
  33. next    ;
  34.  
  35.  
  36. desc
  37. @resolving the UUCP address
  38. (the earlier versions are lost :-(
  39. @
  40.  
  41.  
  42. 2.1
  43. log
  44. @Version 2.0 check in
  45. @
  46. text
  47. @/*
  48.  *  resolve.c
  49.  *
  50.  *  Routines to resolve mail address
  51.  *
  52.  * This program is free software; you can redistribute it and/or
  53.  * modify it under the terms of the GNU General Public License as
  54.  * published by the Free Software Foundation; either version 2 of
  55.  * the License, or (at your option) any later version.
  56.  *
  57.  * This program is distributed in the hope that it will be useful,
  58.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  59.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  60.  * General Public License for more details.
  61.  *
  62.  * You should have received a copy of the GNU General Public License
  63.  * along with this program; if not, write to the Free Software
  64.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  65.  *
  66.  * $Log: resolve.c,v $
  67.  * Revision 1.4  1993/11/20  21:03:02  Aussem
  68.  * output of the debug msg changed
  69.  *
  70.  * Revision 1.3  1993/11/20  20:19:25  Aussem
  71.  * extended Debug options
  72.  *
  73.  * Revision 1.2  1993/10/26  23:05:24  Aussem
  74.  * smail -OA torfhh!test!root now reports really
  75.  * torfhh!test!root
  76.  *
  77.  * Revision 1.1  1993/10/24  00:20:08  Aussem
  78.  * Initial revision
  79.  *
  80.  *
  81.  */
  82.  
  83. static char     *rcsid="$Id: resolve.c,v 1.4 1993/11/20 21:03:02 Aussem Exp Aussem $";
  84.  
  85. #include    <ctype.h>
  86. #include    <stdio.h>
  87. #include    "defs.h"
  88.  
  89. extern int exitstat;        /* set if address doesn't resolve     */
  90. extern enum ehandle handle;    /* what mail we can handle        */
  91. extern enum edebug debug;    /* verbose and debug modes        */
  92. extern enum erouting routing;    /* when to route addresses        */
  93. extern char hostdomain[];    /* */
  94. extern char hostname[];        /* */
  95. extern char *pathfile;        /* location of path database        */
  96. extern int getcost;        /* get path cost even if not routing    */
  97. extern char smarthost[];
  98.  
  99. char *sform();
  100.  
  101. /*
  102. **
  103. **  rsvp(): how to resolve addresses.
  104. **
  105. **  After parsing an address into <form>, the resolved form will be
  106. **  rsvp( form ).  If == ROUTE, we route the parsed address and parse again.
  107. **
  108. */
  109.  
  110. # define rsvp(a) table[(int)a][(int)handle]
  111.  
  112. enum eform table[5][3] = {
  113. /*    all        justuucp    none */
  114. {    ERROR,         ERROR,         ERROR },     /* error */
  115. {    LOCAL,         LOCAL,         LOCAL },     /* local */
  116. {    ROUTE,         LOCAL,         LOCAL },     /* domain */
  117. {    UUCP,         UUCP,         LOCAL },     /* uucp */
  118. {    ERROR,         ERROR,         ERROR }};    /* route */
  119.  
  120. /*
  121. **
  122. **  resolve(): resolve addresses to <host, user, form>.
  123. **
  124. **  This is a gnarly piece of code, but it does it all.  Each section 
  125. **  is documented.
  126. **
  127. */
  128.  
  129. enum eform
  130. resolve( address, domain, user , cost)
  131. char *address;                /* the input address     */
  132. char *domain;                /* the returned domain     */
  133. char *user;                /* the returned user     */
  134. int *cost;                /* the returned cost     */
  135. {
  136.     enum eform form;        /* the returned form    */ 
  137.     enum eform parse();        /* to crack addresses    */
  138.     int parts;            /* to ssplit addresses    */
  139.     char *partv[MAXPATH];        /* "  "      "        */
  140.     char temp[SMLBUF];        /* "  "      "        */
  141.     int i;
  142.         
  143.  
  144. /*
  145. **  If we set REROUTE and are prepared to deliver UUCP mail, we split the 
  146. **  address apart at !'s and try to resolve successively larger righthand 
  147. **  substrings until we succeed.  Otherwise, we just resolve the whole thing 
  148. **  once.
  149. */
  150.     if ((routing == REROUTE) && (rsvp( UUCP ) == UUCP)) {
  151.         parts = ssplit( address, '!', partv );
  152.     } else {
  153.         parts = 1;
  154.         partv[0] = address;
  155.     }
  156. /*
  157. **  This for(i) loop selects successively larger
  158. **  righthand substrings of the address.
  159. */
  160.     for( i = parts - 1; i >= 0; i-- ) {
  161. /*
  162. **  Parse the address.
  163. */
  164.         (void) strcpy( temp, partv[i] );
  165.         form = parse( temp, domain, user );
  166.  
  167. print_error(NOTICE,"parse address '%s' = '%s' @@ '%s' (%s)\n",
  168.     temp,user,domain,sform(form));
  169.  
  170. /*
  171. **  If we are looking at a substring (that's not the entire string)
  172. **  which parses to a LOCAL address, we skip to the next larger substring.
  173. */
  174.         if((i != 0) && (form == LOCAL))
  175.             continue;
  176. /*
  177. **  Routing, when required, is the next step.
  178. **  We route the address if we have a ROUTE form
  179. **  or if we have a UUCP form and we are told to
  180. **  route ALWAYS or REROUTE (i.e., routing != JUSTDOMAIN)
  181. */
  182.         if((rsvp( form ) == ROUTE)
  183.          ||((rsvp( form ) == UUCP) && (routing != JUSTDOMAIN ))) {
  184.  
  185.             int look_smart = 0;
  186. /*
  187. **       if the host is not found the mail cannot be delivered
  188. **            if((routing == REROUTE) && (i == 0)) {
  189. **
  190. **       Now the mail will be delivered to smarthost anyway
  191. */
  192.             if(i == 0) {
  193.                 look_smart = 1; /* last chance */
  194.             }
  195.  
  196.             /* route() puts the new route in 'temp' */
  197.             if(route(domain,user,look_smart,temp,cost) != EX_OK) {
  198.                 continue;    /* If routing fails, try
  199.                         /* next larger substring.
  200.                         /* */
  201.             }
  202. /*
  203. **  After routing, reparse the new route into domain and user. 
  204. */
  205.             form = parse( temp, domain, user );
  206.  
  207. print_error(NOTICE,"parse route '%s' = '%s' @@ '%s' (%s)\n",
  208.     temp,user,domain,sform(form));
  209.  
  210.         } else if((getcost) && (rsvp(form) == UUCP)) {
  211.             /* get the cost of the route
  212.             ** even if we're not going route the mail.
  213.             ** this allows smart decisions about using
  214.             ** the -r flag to uux when we're not routing.
  215.             */
  216.             char junk[SMLBUF];
  217.             if(route(domain,user,0,junk,cost) != EX_OK) {
  218.                 continue;    /* If routing fails, try
  219.                         /* next larger substring.
  220.                         /* */
  221.             }
  222.         }
  223.         break;    /* route is resolved */
  224.     }
  225. /*
  226. **  For LOCAL mail in non-local format, we rewrite the full address into 
  227. **  <user> and leave <domain> blank.
  228. */
  229.     if ((rsvp( form ) == LOCAL) && (form != LOCAL )) {
  230.         build( domain, user, form, temp );
  231.         (void) strcpy( user, temp );
  232.         (void) strcpy( domain, "" );
  233.         form = LOCAL;
  234.     }
  235. /*
  236. **  If we were supposed to route an address but failed (form == ERROR),
  237. **  or after routing we are left with an address that still needs to
  238. **  be routed (rsvp( form ) == ROUTE), complain.
  239. */
  240.     if ((form == ERROR) || (rsvp( form ) == ROUTE )) {
  241.         exitstat = EX_NOHOST;
  242.         print_error(WARNING,"resolve failed '%s' = '%s' @@ '%s' (%s)\n",
  243.             address, user, domain, sform(form));
  244.         form = ERROR;
  245.     } else {
  246.         print_error(NOTICE,"resolve '%s' = '%s' @@ '%s' (%s)\n",
  247.             address, user, domain, sform(form));
  248.     }
  249.     return ( form );
  250. }
  251.  
  252. /*
  253. **
  254. **  route(): route domain, plug in user.
  255. **
  256. **  Less complicated than it looks.  Each section is documented.
  257. **
  258. */
  259.  
  260. route(domain, user, look_smart, result, cost)
  261. char *domain;            /* domain or host name     */
  262. char *user;            /* user name         */
  263. int look_smart;            /* do we try to route through a smarter host? */
  264. char *result;            /* output route     */
  265. int *cost;            /* cost of output route */
  266. {
  267.     int    uucpdom = 0;
  268.     int    domains, step;            /* to split domain    */
  269.     char    *domainv[MAXDOMS];        /* "  "     "        */
  270.     char    temp[SMLBUF], path[SMLBUF];
  271.     char *p_tmp;
  272.  
  273. /*
  274. **  Fully qualify the domain, and then strip the last (top level domain)
  275. **  component off, so that we look it up separately.
  276. */
  277.     temp[0] = '.';
  278.     (void) strcpy(temp+1, domain );
  279.  
  280.     domains = ssplit( temp+1, '.', domainv );
  281.  
  282. /*
  283. ** check target domain for the local host name and host domain.
  284. ** if it matches, then skip the lookup in the database.
  285. ** this prevents mail loops for cases where SMARTHOST is defined
  286. ** in the routing table, but the local host is not.  It also is
  287. ** a little faster when the local host is the target domain.
  288. */
  289.     if((strcmpic(domain, hostname) == 0)
  290.     || (strcmpic(domain, hostdomain) == 0)) {
  291.         step = 0;
  292.         *cost = 0;
  293.         (void) strcpy(path, "%s");
  294. print_error(NOTICE,"'%s' is local\n", domain);
  295.         goto route_complete;
  296.     }
  297.  
  298.     /* If the domain ends in .UUCP, trim that off. */
  299.     if((domains > 0) && isuucp(domainv[domains-1])) {
  300.         domains--;
  301.         domainv[domains][-1] = '\0';
  302.         uucpdom = 1;
  303.     }
  304. /*
  305. **  Try to get the path for successive components of the domain.
  306. **  Example for osgd.cb.att.uucp:
  307. **    osgd.cb.att
  308. **    cb.att
  309. **    att
  310. **    uucp ( remember stripping top level? )
  311. **    SMARTHOST
  312. **  Returns with error if we find no path.
  313. */
  314.     for(step = 0; (step < domains); step++) {
  315.         if((getpath(domainv[step]-1, path, cost) == EX_OK) /* w/ dot */
  316.         || (getpath(domainv[step]  , path, cost) == EX_OK))/* no dot */
  317.             break;
  318.     }
  319.  
  320.  
  321.     if(step == domains) {
  322.     /*
  323.     ** we've looked at each component of the domain without success
  324.     */
  325.         /*
  326.         ** if we don't look up for smarthost return (RTA)
  327.         */
  328.         if(look_smart==0)
  329.             return( EX_NOHOST );
  330.  
  331.         /*
  332.         ** If domain is a UUCP address, look for a UUCP gateway.
  333.         */
  334.         if((uucpdom == 0) || (getpath(".UUCP", path, cost) != EX_OK)) {
  335.             /*
  336.             ** The domain not is a UUCP address, or we can't
  337.             ** find a UUCP gateway.  If this is our last chance,
  338.             ** look for a smarter host to deliver the mail.
  339.             */
  340.             if(getpath(smarthost, path, cost) != EX_OK) {
  341.                 /*
  342.                 ** All our efforts have been in vain.
  343.                 ** Tell them the bad news.
  344.                 */
  345. #ifdef SMARTMAIL
  346.                 print_error(NOTICE,"'%s' failed, sending it to smarthost '%s'\n", domain,smarthost);
  347.                 /* only use the last component of smarthost */
  348.                 p_tmp=index(smarthost,'.');
  349.                 if(p_tmp)
  350.                *p_tmp='\0';
  351.                 p_tmp=index(smarthost,'!');
  352.                 if(p_tmp)
  353.                *p_tmp='\0';
  354.             step=0;sprintf(path,"%s!%s!%%s",smarthost,domain);
  355.             *cost=0;
  356. #else
  357.                 print_error(NOTICE,"'%s' failed\n", domain);
  358.                 return( EX_NOHOST );
  359. #endif
  360.             }
  361.         }
  362.     }
  363.  
  364. route_complete:
  365.  
  366. print_error(NOTICE,"'%s' (%s) = '%s' (%d)\n", domain, domainv[step]?domainv[step]:"NULL", path, *cost);
  367.  
  368. /*
  369. **  If we matched on the entire domain name, this address is fully resolved,
  370. **  and we plug <user> into it.  If we matched on only part of the domain
  371. **  name, we plug <domain>!<user> in.
  372. */
  373.     build(domain, user, (step == 0) ? LOCAL : UUCP, temp);
  374.     (void) sprintf(result, path, temp);
  375.     return( EX_OK );
  376. }
  377. @
  378.  
  379.  
  380. 1.4
  381. log
  382. @output of the debug msg changed
  383. @
  384. text
  385. @d21 3
  386. d37 1
  387. a37 1
  388. static char     *rcsid="$Id: resolve.c,v 1.3 1993/11/20 20:19:25 Aussem Exp Aussem $";
  389. @
  390.  
  391.  
  392. 1.3
  393. log
  394. @extended Debug options
  395. @
  396. text
  397. @d21 3
  398. d34 1
  399. a34 1
  400. static char     *rcsid="$Id: resolve.c,v 1.2 1993/10/26 23:05:24 Aussem Exp Aussem $";
  401. d118 1
  402. a118 1
  403. print_error(NOTICE,"resolve: parse address '%s' = '%s' @@ '%s' (%s)\n",
  404. d158 1
  405. a158 1
  406. print_error(NOTICE,"resolve: parse route '%s' = '%s' @@ '%s' (%s)\n",
  407. d245 1
  408. a245 1
  409. print_error(NOTICE,"route: '%s' is local\n", domain);
  410. d297 1
  411. a297 1
  412.                 print_error(NOTICE,"route '%s' failed, sending it to smarthost '%s'\n", domain,smarthost);
  413. d308 1
  414. a308 1
  415.                 print_error(NOTICE,"route '%s' failed\n", domain);
  416. d317 1
  417. a317 1
  418. print_error(NOTICE,"route:  '%s' (%s) = '%s' (%d)\n", domain, domainv[step]?domainv[step]:"NULL", path, *cost);
  419. @
  420.  
  421.  
  422. 1.2
  423. log
  424. @smail -OA torfhh!test!root now reports really
  425. torfhh!test!root
  426. @
  427. text
  428. @d21 4
  429. d31 1
  430. a31 1
  431. static char     *rcsid="$Id: resolve.c,v 1.1 1993/10/24 00:20:08 Aussem Exp Aussem $";
  432. d115 1
  433. a115 1
  434. DEBUG("resolve: parse address '%s' = '%s' @@ '%s' (%s)\n",
  435. d155 1
  436. a155 1
  437. DEBUG("resolve: parse route '%s' = '%s' @@ '%s' (%s)\n",
  438. a157 3
  439. if(debug==NO)
  440.     printf("Ok, mail sent to %s via %s\n",  user, domain);
  441.  
  442. d184 1
  443. a184 1
  444. **  If we were supposed to route an address but failed (form == ERROR), 
  445. d190 1
  446. a190 1
  447.         ADVISE("resolve failed '%s' = '%s' @@ '%s' (%s)\n",
  448. d194 1
  449. a194 1
  450.         ADVISE("resolve '%s' = '%s' @@ '%s' (%s)\n",
  451. d242 1
  452. a242 1
  453. DEBUG("route: '%s' is local\n", domain);
  454. d294 1
  455. a294 1
  456.                 DEBUG("route '%s' failed, sending it to smarthost '%s'\n", domain,smarthost);
  457. d305 1
  458. a305 1
  459.                 DEBUG("route '%s' failed\n", domain);
  460. d314 1
  461. a314 1
  462. DEBUG("route:  '%s' (%s) = '%s' (%d)\n", domain, domainv[step]?domainv[step]:"NULL", path, *cost);
  463. @
  464.  
  465.  
  466. 1.1
  467. log
  468. @Initial revision
  469. @
  470. text
  471. @d20 3
  472. a22 1
  473.  * $Log$
  474. d24 1
  475. d27 1
  476. a27 1
  477. static char     *rcsid="$Id$";
  478. d130 7
  479. a136 2
  480.  
  481.             if((routing == REROUTE) && (i == 0)) {
  482. d267 1
  483. d273 6
  484. d287 1
  485. a287 2
  486.             if((look_smart == 0)
  487.             || (getpath(smarthost, path, cost) != EX_OK)) {
  488. @
  489.